package com.cjc.sport.util;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;

//import cn.xyz.commons.support.spring.SpringBeansUtils;

/**
 * 解析Http工具类
 */
public final class HttpUtil {
    //    public static ConfigUtils configUtils = SpringBeansUtils.getContext().getBean(ConfigUtils.class);

    /**
     * 请求类
     */
    public static class Request {

        /**
         * @date map对象
         */
        private Map<String, Object> data = new HashMap<String, Object>();
        /**
         * 请求方法
         */
        private RequestMethod method;
        /**
         * 字符串
         */
        private String spec;

        public Request() {
            super();
        }

        public Request(Map<String, Object> data, String spec) {
            super();
            this.data = data;
            this.spec = spec;
        }

        public Request(Map<String, Object> data, RequestMethod method, String spec) {
            super();
            this.data = data;
            this.method = method;
            this.spec = spec;
        }

        /**
         * get
         * @return get
         */
        public Map<String, Object> getData() {
            return data;
        }

        /**
         * get
         * @return get
         */
        public RequestMethod getMethod() {
            return method;
        }

        /**
         * get
         * @return get
         */
        public String getSpec() {
            return spec;
        }

        /**
         * set
         * @param data set
         */
        public void setData(Map<String, Object> data) {
            this.data = data;
        }

        /**
         * set
         * @param method set
         */
        public void setMethod(RequestMethod method) {
            this.method = method;
        }

        /**
         * set
         * @param spec set
         */
        public void setSpec(String spec) {
            this.spec = spec;
        }

    }

    /**
     * 枚举
     */
    public enum RequestMethod {
        /**
         * 注释
         */
        DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE
    }

    /**
     * getBytes
     * @param data 数据
     * @return byte
     * @throws Exception 异常
     */
    private static byte[] getBytes(Map<String, Object> data) throws Exception {
        StringBuffer sb = new StringBuffer();
        for (String key : data.keySet()) {
            sb.append(key).append('=').append(data.get(key)).append('&');
        }
        return sb.substring(0, sb.length() - 1).toString().getBytes("UTF-8");
    }

    /**
     * get
     * @param request 请求对象
     * @return 字符串
     * @throws Exception 异常
     */
    public static String get(Request request) throws Exception {
        URL url = new URL(buildSpec(request));
        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
        urlConn.setDoOutput(true);
        urlConn.setDoInput(true);
        urlConn.setRequestMethod("GET");

        return FileUtil.readAll(urlConn.getInputStream());
    }

    /**
     * buildSpec
     * @param request 请求对象
     * @return 字符串
     */
    private static String buildSpec(Request request) {
        Map<String, Object> params = request.getData();
        StringBuffer sb = new StringBuffer();
        sb.append(request.getSpec());
        if (!params.isEmpty()) {
            sb.append("?");
        }
        for (String key : params.keySet()) {
            sb.append(key).append('=').append(params.get(key)).append('&');
        }
        String spec = sb.substring(0, sb.length() - 1);
        System.out.println(spec);
        return spec;
    }

    /**
     * asString
     * @param request 请求对象
     * @return 字符串
     * @throws Exception 异常
     */
    public static String asString(Request request) throws Exception {
        URL url = new URL(request.getSpec());
        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
        urlConn.setDoOutput(true);
        urlConn.setDoInput(true);
        urlConn.setRequestMethod("POST");
        // urlConn.setRequestMethod(method);
//        Map<String, Object> map = configUtils.getMap();
//        urlConn.setRequestProperty("Content-Type",map.get("Content-Type").toString());
//        urlConn.setRequestProperty("Authorization",map.get("Authorization").toString());
        urlConn.setUseCaches(false);
        urlConn.setInstanceFollowRedirects(true);
//        System.out.println("Content-Type:"+map.get("Content-Type").toString());
//        System.out.println("Authorization:"+map.get("Authorization").toString());
        if (null != request.getData() && !request.getData().isEmpty()) {
//            Object json = JSON.toJSON(request.getData());
            OutputStream out = urlConn.getOutputStream();
            out.write(getBytes(request.getData()));
            out.flush();
            out.close();
        }

        InputStream inputStream = urlConn.getInputStream();
        return FileUtil.readAll(inputStream);
    }

    /**
     * asBean
     * @param request 请求对象
     * @param clazz 泛型
     * @param <T> 泛型
     * @return json
     * @throws Exception 异常
     */
    @SuppressWarnings("unchecked")
    public static <T> T asBean(Request request, Class<?> clazz) throws Exception {
        String text = asString(request);

        return (T) JSON.parseObject(text, clazz);
    }


    /**
     * asBean
     * @param data map对象
     * @param spec spec
     * @param clazz clazz
     * @param <T> 泛型
     * @return json
     * @throws Exception 异常
     */
    public static <T> T asBean(Map<String, Object> data, String spec, Class<?> clazz) throws Exception {
        return asBean(new Request(data, spec), clazz);
    }

    /**
     * getBytes
     * @param object 对象
     * @return byte
     */
    public static byte[] getBytes(Object object) {
        SerializeWriter out = new SerializeWriter();
        JSONSerializer.write(out, object);
        return out.toBytes("UTF-8");
    }
}
